<!--
 * @Author: howcode 1051495009@qq.com
 * @Date: 2024-08-07 14:52:42
 * @LastEditors: howcode 1051495009@qq.com
 * @LastEditTime: 2025-01-21 14:35:58
 * @Description: 
-->
<template>
  <div class="center-report" id="three-container" ref="canvasContainer">
    
  </div>
</template>

<script>
import * as THREE from "three"
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader"
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls"
// 引入dat.gui.js的一个类GUI
// import { GUI } from "three/examples/jsm/libs/lil-gui.module.min.js"

import GLTFFile from "@/assets/gltf/jg.gltf"
import gsap from "gsap"
export default {
  data() {
    return {
      sceneType: 1,
      scenceObj:{
        1:{
          camera:{x:-3.15670515828823,y:4.563979918447152,z:6.955703906625154},
          controls:{x:-1.9133200880769485,y:-0.4919324102894345,z:0.14950620783316043},
          scale:{x:1,y:1,z:1},
          rotation:{x:-0.6389026001051268,y:-0.14561195906142932,z:-0.10736996780596032}
        },
        2:{
          camera:{x:0.03619489710155599,y:-0.07221557928358369,z:2.5487711761445233},
          controls:{x:-0.5310516045625422,y:-1.1947009393014254,z:0.23461793928963348},
          scale:{x:1,y:1,z:1},
          rotation:{x:-0.451618103903698,y:0.2170703471235094,z:0.10408800140069771}
        }
      },
      renderer:null,
      jg1Mesh1:null,
      jg1Mesh2:null,
      jg1Mesh3:null,
      jg1Status:false,
      jg2Status:true,
      jg3Status:false,
    }
  },
  mounted() {
    this.removeRendererDomElement();
    this.initGltf()
  },
  destroyed(){
    this.removeRendererDomElement();
  },
  methods: {
    translateCamera(camera, controls) {
      const timeLine1 = gsap.timeline()
      const timeLine2 = gsap.timeline()
      const timeLine3 = gsap.timeline()
      const target = new THREE.Vector3(this.scenceObj[this.sceneType].controls.x,this.scenceObj[this.sceneType].controls.y,this.scenceObj[this.sceneType].controls.z)
      const position = new THREE.Vector3(this.scenceObj[this.sceneType].camera.x,this.scenceObj[this.sceneType].camera.y,this.scenceObj[this.sceneType].camera.z)
      const rotation = new THREE.Vector3(this.scenceObj[this.sceneType].rotation.x,this.scenceObj[this.sceneType].rotation.y,this.scenceObj[this.sceneType].rotation.z)
      timeLine1.to(camera.position, {
        x: position.x,
        y: position.y,
        z: position.z,
        duration: 1,
        ease: "power2.inOut"
      })
      timeLine2.to(controls.target, {
        x: target.x,
        y: target.y,
        z: target.z,
        duration: 1,
        ease: "power2.inOut"
      })
      timeLine3.to(camera.rotation, {
        x: rotation.x,
        y: rotation.y,
        z: rotation.z,
        duration: 1,
        ease: "power2.inOut"
      })
    },
    removeRendererDomElement() {
      if (!this.renderer) return;
      // 获取渲染器的DOM元素
      const rendererDomElement = this.renderer.domElement;

      // 检查是否已添加到DOM中
      if (this.$refs.canvasContainer && this.$refs.canvasContainer.contains(rendererDomElement)) {
          // 移除DOM元素
          this.$refs.canvasContainer.removeChild(rendererDomElement);
      }
    },
    // 获取井盖状态
    getJGStatus(){
      const timeLine1 = gsap.timeline()
      const timeLine2 = gsap.timeline()
      const timeLine3 = gsap.timeline()
      setInterval(() => {
        timeLine1.to(this.jg1Mesh1.rotation, {
          z: !this.jg1Status ? 0 : Math.PI / -1.6,
          duration: 1,
          ease: "power2.inOut"
        })
        timeLine2.to(this.jg1Mesh2.rotation, {
          z: !this.jg2Status ? 0 : Math.PI / -1.6,
          duration: 1,
          ease: "power2.inOut"
        })
        timeLine3.to(this.jg1Mesh3.rotation, {
          z: !this.jg3Status ? 0 : Math.PI / -1.6,
          duration: 1,
          ease: "power2.inOut"
        })
        this.jg1Status = !this.jg1Status;
        this.jg2Status = !this.jg2Status;
        this.jg3Status = !this.jg3Status;
      }, 2000);
    },
    initGltf() {
      const scene = new THREE.Scene()
      const width = this.$refs.canvasContainer.offsetWidth
      const height = this.$refs.canvasContainer.offsetHeight
      const camera = new THREE.PerspectiveCamera(80, width / height, 0.1, 1000)
      camera.aspect = width / height
      camera.updateProjectionMatrix()
      // 添加点光源
      const pointLight = new THREE.PointLight(0xffffff, 1.0)
      pointLight.position.set(400, 200, 300)
      scene.add(pointLight)
      const gltfLoader = new GLTFLoader()
      gltfLoader.load(GLTFFile, (gltf) => {
        const model = gltf.scene
        this.jg1Mesh1 = model.children[0].children[1]
        this.jg1Mesh2 = model.children[0].children[2]
        this.jg1Mesh3 = model.children[0].children[3]
        model.scale.set(0.5, 0.5, 0.5)
        model.position.set(0, -2, 0)
        scene.add(model)
        this.getJGStatus();
        // 点击事件
        addEventListener("click", (event) => {
          const py = event.offsetY
          const px = event.offsetX
          const x = (px / width) * 2 - 1
          const y = -(py / height) * 2 + 1
          // 创建一个射线投射器
          const raycaster = new THREE.Raycaster()
          raycaster.setFromCamera(new THREE.Vector2(x, y), camera)
          const intersects = raycaster.intersectObjects(model.children[0].children)
          if (intersects.length > 0) {
            this.sceneType = this.sceneType == 1 ? 2 : 1
            this.translateCamera(camera, controls)
          }
        })
      })
      this.renderer = new THREE.WebGLRenderer({
        alpha: true, // 启用透明度
        antialias: true // 启用抗锯齿
      })
      this.renderer.outputEncoding = THREE.sRGBEncoding
      this.renderer.setSize(width, height)
      this.$refs.canvasContainer.appendChild(this.renderer.domElement)
      const controls = new OrbitControls(camera, this.renderer.domElement)
      controls.enableDamping = true
      this.translateCamera(camera, controls)
      const render = () => {
        controls.update()
        this.renderer.render(scene, camera)
        requestAnimationFrame(render)
      }
      render()
    },
  }
}
</script>
<style lang="scss" scoped>
.center-report {
  width: calc(100% - .375rem - .375rem);
  height: calc(100% - 2.5rem);
  position: absolute;
  top: 1.875rem;
  left: 50%;
  transform: translateX(-50%);
  
}
</style>